package com.ruoyi.work.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.CoordinateUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.OpenStreetMapUtil;
import com.ruoyi.common.websocket.MsgType;
import com.ruoyi.common.websocket.WebSocketMessage;
import com.ruoyi.websocket.WebSocketServer;
import com.ruoyi.work.domain.TbEquTrain;
import com.ruoyi.work.domain.TbWorkOrder;
import com.ruoyi.work.domain.vo.LocationTrainVo;
import com.ruoyi.work.service.ITbEquTrainService;
import com.ruoyi.work.service.ITbWorkOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.work.mapper.TbLocationTrainMapper;
import com.ruoyi.work.domain.TbLocationTrain;
import com.ruoyi.work.service.ITbLocationTrainService;

import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 车辆位置Service业务层处理
 *
 * @author szm
 * @date 2025-09-28
 */
@Slf4j
@Service
public class TbLocationTrainServiceImpl extends ServiceImpl<TbLocationTrainMapper, TbLocationTrain> implements ITbLocationTrainService {

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private WebSocketServer webSocket;
    @Autowired
    private ITbEquTrainService tbEquTrainService;
    @Autowired
    private ITbWorkOrderService tbWorkOrderService;

    @Override
    public boolean insertTbLocationTrain(TbLocationTrain tbLocationTrain) throws IOException {
        boolean b = false;
        try {
            tbLocationTrain.setCreateTime(new Date());

            TbEquTrain equTrain = new TbEquTrain();
            List<TbEquTrain> equTrains = tbEquTrainService.lambdaQuery().eq(TbEquTrain::getEquNo, tbLocationTrain.getTerminaPhone()).list();
            if (equTrains.size() > 0) {
                equTrain = equTrains.get(0);
            } else {
                log.info("定位设备和车辆未绑定");
                return false;
            }

            double[] locatin = CoordinateUtils.wgs84ToGcj02(Double.parseDouble(tbLocationTrain.getLongitude()), Double.parseDouble(tbLocationTrain.getLatitude()));
            log.info("获取的数据：" + JSON.toJSONString(locatin));
            if (locatin != null) {
                tbLocationTrain.setLongitude(String.valueOf(locatin[0]));
                tbLocationTrain.setLatitude(String.valueOf(locatin[1]));
            } else {
                log.info("坐标转换失败!!");
                return false;
            }

            List<TbWorkOrder> orderList = tbWorkOrderService.lambdaQuery().like(TbWorkOrder::getEquNo, tbLocationTrain.getTerminaPhone()).eq(TbWorkOrder::getStatus, "1").list();
            if (orderList.size() > 0) {
                TbWorkOrder tbWorkOrder = orderList.get(0);
                tbLocationTrain.setWorkNo(tbWorkOrder.getWorkNo());
                tbLocationTrain.setLineName(tbWorkOrder.getLineName());
                tbLocationTrain.setTrainNo(tbWorkOrder.getTrainNo());
            } else {
                updateEquElety(tbLocationTrain, equTrain);
                log.info("该设备暂无任务!!!");
                return false;
            }

            QueryWrapper<TbLocationTrain> wrapper = new QueryWrapper<>();
            TbLocationTrain train = new TbLocationTrain();
            train.setLongitude(tbLocationTrain.getLongitude());
            train.setLatitude(tbLocationTrain.getLatitude());
            train.setTerminaPhone(tbLocationTrain.getTerminaPhone());
            train.setWorkNo(tbLocationTrain.getWorkNo());
            wrapper.setEntity(train);
            List<TbLocationTrain> locatinTrains = this.list(wrapper);
            log.info("查询的数据：" + JSON.toJSONString(locatinTrains));

            if (CollectionUtil.isEmpty(locatinTrains)) {
                log.info("开始组装数据");
                tbLocationTrain.setStatus("go");
                tbLocationTrain.setCreateBy("admin");
                tbLocationTrain.setCreateBy("admin");
                tbLocationTrain.setCreateTime(new Date());
                tbLocationTrain.setUpdateTime(new Date());

                Boolean key = redisCache.hasKey(CacheConstants.JT808_HART + tbLocationTrain.getTerminaPhone());
                log.info("key值 【" + CacheConstants.JT808_HART + tbLocationTrain.getTerminaPhone() + "】状态：" + key);
                if (key) {
                    TbLocationTrain locationTrain = baseMapper.getByPhono(tbLocationTrain.getTerminaPhone(), tbLocationTrain.getTerminaPhone());
                    if (locationTrain != null) {
                        Date currTime = tbLocationTrain.getLastTime();
                        Date lastTime = locationTrain.getLastTime();
                        int different = DateUtils.differentByMillisecond(currTime, lastTime);
                        if (different > 5) {
                            locationTrain.setStatus("end");
                            tbLocationTrain.setStatus("start");
                        } else {
                            locationTrain.setStatus("go");
                        }
                        this.updateById(locationTrain);
                    } else {
                        tbLocationTrain.setStatus("start");
                    }
                    redisCache.deleteObject(CacheConstants.JT808_HART + tbLocationTrain.getTerminaPhone());
                } else {
                    tbLocationTrain.setStatus("go");
                }

                if ("start".equals(tbLocationTrain.getStatus()) || "end".equals(tbLocationTrain.getStatus())) {
                    String gdlocatin = OpenStreetMapUtil.getLocatin(tbLocationTrain.getLongitude() + "," + tbLocationTrain.getLatitude());
                    JSONObject object = JSONObject.parseObject(gdlocatin);
                    JSONObject jsonObject = object.getJSONObject("regeocode");
                    String formatted_address = jsonObject.getString("formatted_address");
                    jsonObject.remove("aois");
                    jsonObject.remove("pois");
                    tbLocationTrain.setRemark(JSON.toJSONString(jsonObject));
                    tbLocationTrain.setLocationName(formatted_address);
                    updateEquElety(tbLocationTrain, equTrain);
                    log.info("设备位置更新完成!!!");
                }

                log.info("数据组装完成");
                b = this.saveOrUpdate(tbLocationTrain);
                log.info("位置信息写入数据库:" + JSON.toJSONString(tbLocationTrain));

                //this.sendMessage(tbLocationTrain);
            } else {
                log.info("坐标【" + tbLocationTrain.getLongitude() + "," + tbLocationTrain.getLatitude() + "】已存在，无需重复写入");
                updateEquElety(tbLocationTrain, equTrain);
                log.info("设备电量更新完成!!!");
                b = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return b;
    }

    @Override
    public boolean syncUpdate() {
        try {
            List<TbLocationTrain> trainList = this.lambdaQuery().isNull(TbLocationTrain::getTrainNo).list();

            /*for (TbLocationTrain train : trainList){
                Thread.sleep(1000);
                String locatin = OpenStreetMapUtil.convertLocatin(train.getLongitude()+","+train.getLatitude());
                System.out.println("获取的数据："+locatin);
                JSONObject object = JSONObject.parseObject(locatin);
                if (object.getString("status").equals("1")){

                    String[] locations = object.getString("locations").split(",");

                    train.setWorkNo("JY20251023001");
                    train.setTrainNo("G0801");
                    train.setLongitude(locations[0]);
                    train.setLatitude(locations[1]);
                }

                train.setUpdateTime(new Date());
                this.updateById(train);
            }*/


            for (TbLocationTrain train : trainList) {
                double[] locatin = CoordinateUtils.wgs84ToGcj02(Double.parseDouble(train.getLongitude()), Double.parseDouble(train.getLatitude()));
                System.out.println("获取的数据：" + locatin);
                if (locatin != null) {

                    train.setWorkNo("JY20251023001");
                    train.setTrainNo("G0801");
                    train.setLongitude(String.valueOf(locatin[0]));
                    train.setLatitude(String.valueOf(locatin[1]));
                }

                //train.setCreateBy("admin");
                train.setUpdateTime(new Date());

                this.updateById(train);
            }
            log.info("批量写入数据成功");
            //this.updateBatchById(trainList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    public Map<String, List<LocationTrainVo>> getTrackList() {
        List<TbEquTrain> trains = tbEquTrainService.list();
        Map<String, List<LocationTrainVo>> map = new TreeMap<>();
        for (TbEquTrain train : trains) {
            List<LocationTrainVo> trainVoList = new LinkedList<>();

            List<TbWorkOrder> orderList = tbWorkOrderService.lambdaQuery().eq(TbWorkOrder::getTrainNo, train.getTrainNo())
                    .eq(TbWorkOrder::getStatus, 1).orderByDesc(TbWorkOrder::getCreateBy).list();
            if (CollectionUtil.isNotEmpty(orderList)) {
                TbWorkOrder tbWorkOrder = orderList.get(0);
                List<TbLocationTrain> locationTrainList = this.lambdaQuery().eq(TbLocationTrain::getWorkNo, tbWorkOrder.getWorkNo()).orderByAsc(TbLocationTrain::getLastTime).list();
                if (CollectionUtil.isNotEmpty(locationTrainList)) {
                    for (TbLocationTrain locationTrain : locationTrainList) {
                        LocationTrainVo trainVo = new LocationTrainVo();
                        trainVo.setLastTime(locationTrain.getLastTime());
                        trainVo.setLineName(train.getLineName());
                        trainVo.setLatitude(locationTrain.getLatitude());
                        trainVo.setLongitude(locationTrain.getLongitude());
                        trainVo.setEquNo(locationTrain.getTerminaPhone());
                        trainVo.setWorkNo(locationTrain.getWorkNo());
                        trainVo.setSpeed(locationTrain.getSpeed());
                        trainVo.setTrainNo(locationTrain.getTrainNo());
                        trainVoList.add(trainVo);
                    }
                }
            }
            map.put(train.getTrainNo(), trainVoList);
        }
        return map;
    }

    public void updateEquElety(TbLocationTrain tbLocationTrain, TbEquTrain equTrain) {
        try {
            equTrain.setElectricity(tbLocationTrain.getElectricity());
            equTrain.setLatitude(tbLocationTrain.getLatitude());
            equTrain.setLongitude(tbLocationTrain.getLongitude());
            equTrain.setLocationName(tbLocationTrain.getLocationName());
            equTrain.setUpdateTime(new Date());
            tbEquTrainService.updateById(equTrain);
            log.info("设备更新信息：" + JSON.toJSONString(equTrain));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
